From: mjw@wray-m-3.hpl.hp.com Date: Thu, 30 Sep 2004 14:22:28 +0000 (+0000) Subject: bitkeeper revision 1.1159.96.3 (415c16a40z3XgMlliaGAnrifiHmpNg) X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~17400^2~550^2~2 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22?a=commitdiff_plain;h=d61b7f7baa0f2b9355aa96d0c99bcf5c4d44ad64;p=xen.git bitkeeper revision 1.1159.96.3 (415c16a40z3XgMlliaGAnrifiHmpNg) Move the configuration step for a restored/received domain so that it is as early as possible in the domain construction process. Change domain restore to use xfrd to avoid blocking and double configuration. --- diff --git a/tools/libxc/xc.h b/tools/libxc/xc.h index 06ce01df69..dfc9a9f5d7 100644 --- a/tools/libxc/xc.h +++ b/tools/libxc/xc.h @@ -75,9 +75,10 @@ int xc_shadow_control(int xc_handle, xc_shadow_control_stats_t *stats); -#define XCFLAGS_VERBOSE 1 -#define XCFLAGS_LIVE 2 -#define XCFLAGS_DEBUG 4 +#define XCFLAGS_VERBOSE 1 +#define XCFLAGS_LIVE 2 +#define XCFLAGS_DEBUG 4 +#define XCFLAGS_CONFIGURE 8 struct XcIOContext; int xc_linux_save(int xc_handle, struct XcIOContext *ioctxt); diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 977a60f841..0988055af3 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -245,6 +245,15 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt) } shared_info_frame = op.u.getdomaininfo.shared_info_frame; + if(ioctxt->flags & XCFLAGS_CONFIGURE) + { + if(xcio_configure_domain(ioctxt)) + { + xcio_error(ioctxt, "Configuring domain failed"); + goto out; + } + } + if ( (pm_handle = init_pfn_mapper((domid_t)dom)) == NULL ) goto out; diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index ef1a3c2135..5532d5b98f 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -211,9 +211,9 @@ class XendDomain: @param id: domain id @param notify: send a domain died event if true """ - for info in self.domain_by_name.values(): + for (k, info) in self.domain_by_name.items(): if info.id == id: - del self.domain_by_name[info.name] + del self.domain_by_name[k] if id in self.domain_by_id: info = self.domain_by_id[id] del self.domain_by_id[id] @@ -408,11 +408,15 @@ class XendDomain: @return: deferred """ - def cbok(dominfo): - self._add_domain(dominfo) - return dominfo - deferred = XendDomainInfo.vm_restore(src, progress=progress) - deferred.addCallback(cbok) + if 0: + def cbok(dominfo): + self._add_domain(dominfo) + return dominfo + deferred = XendDomainInfo.vm_restore(src, progress=progress) + deferred.addCallback(cbok) + else: + xmigrate = XendMigrate.instance() + deferred = xmigrate.restore_begin(src) return deferred def domain_get(self, id): diff --git a/tools/python/xen/xend/XendMigrate.py b/tools/python/xen/xend/XendMigrate.py index 9c235e8700..a2bf83389f 100644 --- a/tools/python/xen/xend/XendMigrate.py +++ b/tools/python/xen/xend/XendMigrate.py @@ -295,11 +295,6 @@ class XendMigrateInfo(XfrdInfo): eserver.inject('xend.domain.migrate', [ self.dominfo.name, self.dominfo.id, "begin", self.sxpr() ]) - # Special case for localhost: destroy all devices early. - if 0 and self.dst_host in ["localhost", "127.0.0.1"]: - self.dominfo.restart_cancel() - self.dominfo.cleanup() - #self.dominfo.destroy_console() xfrd.request(['xfr.migrate', self.src_dom, vmconfig, @@ -307,6 +302,19 @@ class XendMigrateInfo(XfrdInfo): self.dst_port, self.live ]) + def xfr_vm_suspend(self, xfrd, val): + def cbok(val): + # Special case for localhost: destroy devices early. + if self.dst_host in ["localhost", "127.0.0.1"]: + self.dominfo.restart_cancel() + self.dominfo.cleanup() + self.dominfo.destroy_console() + return val + + d = XfrdInfo.xfr_vm_suspend(self, xfrd, val) + d.addCallback(cbok) + return d + def xfr_migrate_ok(self, xfrd, val): dom = int(sxp.child0(val)) self.state = 'ok' @@ -381,7 +389,35 @@ class XendSaveInfo(XfrdInfo): [ self.dominfo.name, self.dominfo.id, self.state, self.sxpr() ]) +class XendRestoreInfo(XfrdInfo): + """Representation of a restore in-progress and its interaction with xfrd. + """ + + def __init__(self, xid, file): + XfrdInfo.__init__(self) + self.xid = xid + self.state = 'begin' + self.file = file + + def sxpr(self): + sxpr = ['restore', + ['id', self.xid], + ['file', self.file] ] + return sxpr + def request(self, xfrd): + print '***request>', self.file + log.info('restore BEGIN: ' + str(self.sxpr())) + xfrd.request(['xfr.restore', self.file ]) + + def xfr_restore_ok(self, xfrd, val): + dom = int(sxp.child0(val)) + dominfo = self.xd.domain_get(dom) + self.state = 'ok' + if not self.deferred.called: + self.deferred.callback(dominfo) + + class XendMigrate: """External api for interaction with xfrd for migrate and save. Singleton. @@ -477,6 +513,12 @@ class XendMigrate: info = XendSaveInfo(xid, dominfo, file) return self.session_begin(info) + def restore_begin(self, file): + xid = self.nextid() + info = XendRestoreInfo(xid, file) + return self.session_begin(info) + + def instance(): global inst try: diff --git a/tools/xfrd/xen_domain.c b/tools/xfrd/xen_domain.c index b061a86c4c..5e535301b4 100644 --- a/tools/xfrd/xen_domain.c +++ b/tools/xfrd/xen_domain.c @@ -108,7 +108,10 @@ int xen_domain_snd(Conn *xend, IOStream *io, /** Receive domain state. * Create a new domain and store the received state into it. */ -int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmconfig_n){ +int xen_domain_rcv(IOStream *io, + uint32_t *dom, + char **vmconfig, int *vmconfig_n, + int *configured){ int err = 0; #ifdef _XEN_XFR_STUB_ char buf[1024]; @@ -135,11 +138,13 @@ int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmconfig_n ioctxt->info = iostdout; ioctxt->err = iostderr; ioctxt->configure = domain_configure; + ioctxt->flags |= XCFLAGS_CONFIGURE; err = xc_linux_restore(xcinit(), ioctxt); *dom = ioctxt->domain; *vmconfig = ioctxt->vmconfig; *vmconfig_n = ioctxt->vmconfig_n; + *configured = (ioctxt->flags & XCFLAGS_CONFIGURE); #endif dprintf("< err=%d\n", err); return err; diff --git a/tools/xfrd/xen_domain.h b/tools/xfrd/xen_domain.h index 2b59f502ee..2ea66b743e 100644 --- a/tools/xfrd/xen_domain.h +++ b/tools/xfrd/xen_domain.h @@ -11,7 +11,10 @@ extern int xen_domain_snd(Conn *xend, IOStream *io, uint32_t dom, char *vmconfig, int vmconfig_n, int live); -extern int xen_domain_rcv(IOStream *io, uint32_t *dom, char **vmconfig, int *vmconfig_n); +extern int xen_domain_rcv(IOStream *io, + uint32_t *dom, + char **vmconfig, int *vmconfig_n, + int *configured); extern int xen_domain_configure(uint32_t dom, char *vmconfig, int vmconfig_n); diff --git a/tools/xfrd/xfrd.c b/tools/xfrd/xfrd.c index 9c68afddb1..e2b6e98fa1 100644 --- a/tools/xfrd/xfrd.c +++ b/tools/xfrd/xfrd.c @@ -99,6 +99,8 @@ Sxpr oxfr_hello; // (xfr.hello ) Sxpr oxfr_migrate; // (xfr.migrate ) Sxpr oxfr_migrate_ok;// (xfr.migrate.ok ) Sxpr oxfr_progress; // (xfr.progress ) +Sxpr oxfr_restore; // (xfr.restore ) +Sxpr oxfr_restore_ok;// (xfr.restore.ok ) Sxpr oxfr_save; // (xfr.save ) Sxpr oxfr_save_ok; // (xfr.save.ok) Sxpr oxfr_vm_destroy;// (xfr.vm.destroy ) @@ -113,6 +115,8 @@ void xfr_init(void){ oxfr_migrate = intern("xfr.migrate"); oxfr_migrate_ok = intern("xfr.migrate.ok"); oxfr_progress = intern("xfr.progress"); + oxfr_restore = intern("xfr.restore"); + oxfr_restore_ok = intern("xfr.restore.ok"); oxfr_save = intern("xfr.save"); oxfr_save_ok = intern("xfr.save.ok"); oxfr_vm_destroy = intern("xfr.vm.destroy"); @@ -540,6 +544,14 @@ int xfr_send_migrate_ok(Conn *conn, uint32_t vmid){ return (err < 0 ? err : 0); } +int xfr_send_restore_ok(Conn *conn, uint32_t vmid){ + int err = 0; + + err = IOStream_print(conn->out, "(%s %d)", + atom_name(oxfr_restore_ok), vmid); + return (err < 0 ? err : 0); +} + int xfr_send_save_ok(Conn *conn){ int err = 0; @@ -777,6 +789,46 @@ int xfr_save(Args *args, XfrState *state, Conn *xend, char *file){ return err; } +/** Restore a vm from file. + * + * @return 0 on success, error code otherwise + */ +int xfr_restore(Args *args, XfrState *state, Conn *xend, char *file){ + int err = 0; + IOStream *io = NULL; + int configured=0; + + dprintf("> file=%s\n", file); + io = gzip_stream_fopen(file, "rb"); + if(!io){ + eprintf("> Failed to open %s\n", file); + err = -EINVAL; + goto exit; + } + err = xen_domain_rcv(io, + &state->vmid_new, + &state->vmconfig, &state->vmconfig_n, + &configured); + if(err) goto exit; + if(!configured){ + err = xen_domain_configure(state->vmid_new, state->vmconfig, state->vmconfig_n); + if(err) goto exit; + } + err = xen_domain_unpause(state->vmid_new); + exit: + if(io){ + IOStream_close(io); + IOStream_free(io); + } + if(err){ + xfr_error(xend, err); + } else { + xfr_send_restore_ok(xend, state->vmid_new); + } + dprintf("< err=%d\n", err); + return err; +} + /** Accept the transfer of a vm from another node. * * @param peer connection @@ -787,17 +839,23 @@ int xfr_recv(Args *args, XfrState *state, Conn *peer){ int err = 0; time_t t0 = time(NULL), t1; Sxpr sxpr; + int configured=0; dprintf(">\n"); - err = xen_domain_rcv(peer->in, &state->vmid_new, &state->vmconfig, &state->vmconfig_n); + err = xen_domain_rcv(peer->in, + &state->vmid_new, + &state->vmconfig, &state->vmconfig_n, + &configured); if(err) goto exit; // Read from the peer. This is just so we wait before configuring. // When migrating to the same host the peer must destroy the domain // before we configure the new one. err = Conn_sxpr(peer, &sxpr); if(err) goto exit; - err = xen_domain_configure(state->vmid_new, state->vmconfig, state->vmconfig_n); - if(err) goto exit; + if(!configured){ + err = xen_domain_configure(state->vmid_new, state->vmconfig, state->vmconfig_n); + if(err) goto exit; + } err = xen_domain_unpause(state->vmid_new); if(err) goto exit; // Report new domain id to peer. @@ -878,6 +936,17 @@ int xfrd_service(Args *args, int peersock, struct sockaddr_in peer_in){ if(err) goto exit; err = xfr_save(args, state, conn, file); + } else if(sxpr_elementp(sxpr, oxfr_restore)){ + // Restore message from xend. + char *file; + XfrState _state = {}, *state = &_state; + int n = 0; + + dprintf("> xfr.restore\n"); + err = stringof(sxpr_childN(sxpr, n++, ONONE), &file); + if(err) goto exit; + err = xfr_restore(args, state, conn, file); + } else if(sxpr_elementp(sxpr, oxfr_xfr)){ // Xfr message from peer xfrd. XfrState _state = {}, *state = &_state;